---
id: physics
title: Physics
sidebar_label: Physics
slug: /guides/physics
---

import useBaseUrl from '@docusaurus/useBaseUrl'

# Physics API

:::warning
The API for physics is still work in progress and might change in the future.
:::

:::tip
As physics engine [**bullet3**](https://github.com/bulletphysics/bullet3) is used. We simply provide a JS/JSI wrapper around it.
So it can help to familiarize with their documentation first:
- [Bullet_User_Manual.pdf](https://github.com/bulletphysics/bullet3/blob/master/docs/Bullet_User_Manual.pdf)
:::

<div class="image-container">
  <svg xmlns="http://www.w3.org/2000/svg" width="283" height="535">
    <image href={useBaseUrl("img/demo-coins_physics.gif")} x="18" y="33" width="247" height="469" />
    <image href={useBaseUrl("img/frame.png")} width="283" height="535" />
  </svg>
</div>

Hooks:

The hooks should be used whenever possible.

- [`useWorld`](../api/functions/useWorld)
- [`useRigidBody`](../api/functions/useRigidBody)
- [`useCylinderShape`](../api/functions/useCylinderShape)
- [`useBoxShape`](../api/functions/useBoxShape)
- [`useSphereShape`](../api/functions/useSphereShape)
- [`useStaticPlaneShape`](../api/functions/useStaticPlaneShape)


**Example:**

First we need to create a physics world:

```tsx
import { useWorld } from 'react-native-filament';

function App() {
  const world = useWorld([0, -9.8, 0]);
}
```

Often times you want to create a physical body for an entity (asset) in the scene.
Here are a few helpers you likely will need to accomplish this:

**Get the bounding box of an entity:**

```tsx
const boundingBox = asset.boundingBox // returns an aabb bounding box
const halfExtents = boundingBox.halfExtents
const center = boundingBox.center
```

**Get the transform an entity:**

```tsx
const {transformManager} = useFilamentContext()
const transform = transformManager.getTransform(entity)

// Get the calculated world scale:
const [scaleX, scaleY, scaleZ] = transform.scale
```

**Create a physical shape (resembling the asset)**

```tsx
// useBoxShape expects a vector of halfExtents, so we can just pass the once from our asset
const boxShape = useBoxShape(halfExtents)

// Eventually we need to adjust the local scaling of the shape:
boxShape.localScaling = transform.scale
```

**Create a rigid body**

```tsx
const rigidBody = useRigidBody({
  id: "box",
  mass: 1,
  shape: boxShape,
  transform: transform,
  // Pass the world for the body to be automatically added to the world:
  world: world
})
```

**Update the physical world**

We need to simulate physics every frame:

```tsx
const renderCallback = useCallback(({ timeSinceLastFrame }) => {
  "worklet"

  // This updates the world at 60Hz/60 FPS. If our actual frame rate
  // is different stepSimulation will interpolate the physics.
  world.stepSimulation(timeSinceLastFrame, 1, 1 / 60)
}, [world])
```

**Update the transform of our physic entities**

Now that the physical world has been updated we need to update the transform of our entities.
The `transformManager` has a convenience method for that:

```tsx
const renderCallback = useCallback(({ timeSinceLastFrame }) => {
  "worklet"

  world.stepSimulation(timeSinceLastFrame, 1, 1 / 60)

  // Update our entity:
  transformManager.updateTransformByRigidBody(entity, rigidBody)
}, [world])